package com.jwds.digital.bios.business.service.service.dispatch.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jwds.digital.bios.business.core.exceptions.RecordNotFoundException;
import com.jwds.digital.bios.business.core.infrastructure.dto.dispatch.DispatchInternalTransportReqDTO;
import com.jwds.digital.bios.business.core.infrastructure.dto.dispatch.assembler.DispatchInternalTransportAssembler;
import com.jwds.digital.bios.business.core.infrastructure.dto.feign.BasicStockBinReqDTO;
import com.jwds.digital.bios.business.core.infrastructure.dto.feign.FlowBasicReqDTO;
import com.jwds.digital.bios.business.core.infrastructure.entity.dispatch.DispatchFeed;
import com.jwds.digital.bios.business.core.infrastructure.entity.dispatch.DispatchInternalTransport;
import com.jwds.digital.bios.business.core.infrastructure.entity.dispatch.DispatchRevert;
import com.jwds.digital.bios.business.core.infrastructure.mapper.dispatch.DispatchInternalTransportMapper;
import com.jwds.digital.bios.business.core.infrastructure.vo.dispatch.DispatchFeedRespVO;
import com.jwds.digital.bios.business.core.infrastructure.vo.dispatch.DispatchInternalTransportRespVO;
import com.jwds.digital.bios.business.core.infrastructure.vo.feign.BasicStockBinRespVO;
import com.jwds.digital.bios.business.core.infrastructure.vo.feign.FlowBasicRespVO;
import com.jwds.digital.bios.business.core.utils.FeignResultUtil;
import com.jwds.digital.bios.business.rpc.feign.BasicStockBinFeign;
import com.jwds.digital.bios.business.rpc.feign.FlowBasicFeign;
import com.jwds.digital.bios.business.service.service.dispatch.IDispatchInternalTransportService;
import com.jwds.tdc.framework.application.lib.BaseResponse;
import com.jwds.tdc.framework.application.lib.page.PageRequest;
import com.jwds.tdc.framework.application.lib.page.PageResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 内部转运调度实现类
 *
 * @author 林柏云
 * @date 2024-10-24
 */
@Slf4j
@Service
public class DispatchInternalTransportServiceImpl extends ServiceImpl<DispatchInternalTransportMapper, DispatchInternalTransport> implements IDispatchInternalTransportService {

    @Autowired
    private DispatchInternalTransportMapper baseMapper;
    @Autowired
    private BasicStockBinFeign basicStockBinFeign;
    @Autowired
    private FlowBasicFeign flowBasicFeign;

    @Override
    public DispatchInternalTransportRespVO queryById(Long id) {
        if (id == null) {
            return null;
        }
        DispatchInternalTransport entity = baseMapper.selectById(id);
        return DispatchInternalTransportAssembler.entity2dto(entity);
    }

    @Override
    public PageResponse<DispatchInternalTransportRespVO> page(PageRequest<DispatchInternalTransportReqDTO> request) {
        DispatchInternalTransportReqDTO condition = request.getQueryCondition();
        Page<DispatchInternalTransportRespVO> page = new Page<>(request.getPageIndex(), request.getPageSize());
        IPage<DispatchInternalTransportRespVO> pageData = baseMapper.pageQuery(page, condition);
        return new PageResponse<>((Page<?>) pageData, pageData.getRecords());
    }



    @Override
    public void add(DispatchInternalTransportReqDTO reqDto) {
        DispatchInternalTransport entity = DispatchInternalTransportAssembler.dto2entity(reqDto);
        baseMapper.insert(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchAdd(List<DispatchInternalTransportReqDTO> dtoList) {
        dtoList.forEach(this::add);
    }

    @Override
    public void update(DispatchInternalTransportReqDTO reqDto) {
        DispatchInternalTransport oldEntity = baseMapper.selectById(reqDto.getId());
        if (oldEntity == null) {
            throw new RecordNotFoundException();
        }
        DispatchInternalTransport newEntity = DispatchInternalTransportAssembler.dto2entity(reqDto, oldEntity);
        baseMapper.updateById(newEntity);
    }

    @Override
    public void delete(Long id) {
        DispatchInternalTransport oldEntity = baseMapper.selectById(id);
        if (oldEntity == null) {
            throw new RecordNotFoundException();
        }
        baseMapper.deleteById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchDelete(List<Long> ids) {
        for (Long id : ids) {
            delete(id);
        }
    }

    @Override
    public List<String> StartingPoint(String originPointion) {
        if (originPointion == null){
            throw new RuntimeException();
        }
        ArrayList<String> arrayList = new ArrayList<>();
        LambdaQueryWrapper<DispatchInternalTransport> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DispatchInternalTransport::getOriginPointion,originPointion);
        List<DispatchInternalTransport> list = baseMapper.selectList(queryWrapper);
        for (DispatchInternalTransport datum : list) {
            arrayList.add(datum.getOriginPointion());
        }
        return arrayList;
    }

    @Override
    public List<String> destDevice(String originDevice) {
        if (originDevice == null){
            throw new RuntimeException();
        }
        ArrayList<String> arrayList = new ArrayList<>();
        LambdaQueryWrapper<DispatchInternalTransport> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DispatchInternalTransport::getOriginDevice,originDevice);
        List<DispatchInternalTransport> list = baseMapper.selectList(queryWrapper);
        for (DispatchInternalTransport datum : list) {
            arrayList.add(datum.getDestDevice());
        }
        return arrayList;
    }

    @Override
    public List<String> originDevice(DispatchInternalTransportReqDTO reqDTO) {
        if (reqDTO == null){
            throw new RuntimeException();
        }
        DispatchInternalTransport entity = baseMapper.selectById(reqDTO.getId());
//        通过起点位置的名称获取起点设备的编码
        BasicStockBinReqDTO basicStockBinReqDTO = new BasicStockBinReqDTO();
        basicStockBinReqDTO.setBinName(entity.getOriginPointion());
        List<FlowBasicReqDTO> result =  new ArrayList<>();
        List<BasicStockBinRespVO> binName = FeignResultUtil.getDataFromBaseResponse(basicStockBinFeign.list(basicStockBinReqDTO));
        for (BasicStockBinRespVO datum : binName) {
            FlowBasicReqDTO dto = new FlowBasicReqDTO();
            dto.setStartDeviceCode(datum.getDeviceOut());
            result.add(dto);
        }
//      通过终点位置的名称获取起点的编码
        basicStockBinReqDTO.setBinName(entity.getDestPointion());
        List<BasicStockBinRespVO> binRespList = FeignResultUtil.getDataFromBaseResponse(basicStockBinFeign.list(basicStockBinReqDTO));
        for (BasicStockBinRespVO datum : binRespList) {
            FlowBasicReqDTO dto = new FlowBasicReqDTO();
            dto.setEndDeviceCode(datum.getDeviceIn());
            result.add(dto);
        }
        BaseResponse<List<FlowBasicRespVO>> all = flowBasicFeign.all((FlowBasicReqDTO) result);
        List<FlowBasicRespVO> data = all.getData();
        List<String> list = new ArrayList<>();
        for (FlowBasicRespVO datum : data){
            list.add(datum.getFlowName());
        }
        return list;
    }

    @Override
    public DispatchInternalTransportRespVO execute(DispatchInternalTransportReqDTO reqDTO) {
        DispatchInternalTransport entity = baseMapper.selectById(reqDTO.getId());
//      通过起点位置的名称获取起点设备的编码
        BasicStockBinReqDTO basicStockBinReqDTO = new BasicStockBinReqDTO();
        basicStockBinReqDTO.setBinName(entity.getOriginPointion());
        List<FlowBasicReqDTO> result =  new ArrayList<>();
        List<BasicStockBinRespVO> binName = FeignResultUtil.getDataFromBaseResponse(basicStockBinFeign.list(basicStockBinReqDTO));
        for (BasicStockBinRespVO datum : binName) {
            FlowBasicReqDTO dto = new FlowBasicReqDTO();
            dto.setStartDeviceCode(datum.getDeviceOut());
            result.add(dto);
        }
//        通过终点设备的名称获取起点设备的编码
        basicStockBinReqDTO.setBinCode(entity.getDestPointion());
        List<BasicStockBinRespVO> binCode = FeignResultUtil.getDataFromBaseResponse(basicStockBinFeign.list(basicStockBinReqDTO));
        for (BasicStockBinRespVO datum : binCode) {
            FlowBasicReqDTO dto = new FlowBasicReqDTO();
            dto.setEndDeviceCode(datum.getDeviceIn());
            result.add(dto);
        }
        BaseResponse<List<FlowBasicRespVO>> all = flowBasicFeign.all((FlowBasicReqDTO) result);
        List<FlowBasicRespVO> data = all.getData();
        List<String> list = data.stream().map(FlowBasicRespVO::getFlowName).collect(Collectors.toList());
        entity.setProcessRoute(list.toString());
        baseMapper.updateById(entity);
        DispatchInternalTransportRespVO dispatchInternalTransportRespVO = new DispatchInternalTransportRespVO();
        BeanUtils.copyProperties(entity,dispatchInternalTransportRespVO);
        return dispatchInternalTransportRespVO;
    }

    @Override
    public List<DispatchInternalTransportRespVO> listBlastFurnace(String binName) {
        BasicStockBinReqDTO basicStockBinReqDTO = new BasicStockBinReqDTO();
        basicStockBinReqDTO.setBinName(binName);
        //查询指定的料仓
        List<BasicStockBinRespVO> listBaseStockBin = FeignResultUtil.getDataFromBaseResponse(basicStockBinFeign.list(basicStockBinReqDTO));
        //根据料仓编码查询指定的料仓
        LambdaQueryWrapper<DispatchInternalTransport> queryWrapper= new LambdaQueryWrapper<>();
        queryWrapper.eq(DispatchInternalTransport::getBinCode,listBaseStockBin.stream().findFirst().get().getBinCode());
        List<DispatchInternalTransport> dispatchInternalTransportList = baseMapper.selectList(queryWrapper);
        ArrayList<DispatchInternalTransportRespVO> dispatchInternalTransportRespVOList = new ArrayList<>();
        for (DispatchInternalTransport datum : dispatchInternalTransportList){
            DispatchInternalTransportRespVO dispatchInternalTransportRespVO = new DispatchInternalTransportRespVO();
            BeanUtils.copyProperties(datum,dispatchInternalTransportRespVO);
            dispatchInternalTransportRespVOList.add(dispatchInternalTransportRespVO);
        }
        return dispatchInternalTransportRespVOList;
    }


}
